package com.xpec.c4.service.ioc;

import java.lang.reflect.Field;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.xpec.c4.game.utility.GUID;
import com.xpec.c4.service.annotations.In;
import com.xpec.c4.service.annotations.Out;
import com.xpec.c4.service.common.BaseMessageAction;
import com.xpec.c4.service.contexts.Contexts;
import com.xpec.c4.service.contexts.ScopeType;

/**
 * Contexts管理器
 * 
 * @author lipeilin
 * 
 */
public class IocAction {

	private static final Log log = LogFactory.getLog(IocAction.class);

	/**
	 * 对象注入
	 * 
	 * @param obj
	 */
	public static void inObject(Object obj) {
		// 如果对象==null，直接返回
		if (obj == null) {
			return;
		}
		
		//如果是基本的消息对象，有些字段不用注入，直接设置，算是优化与规范吧
		if (obj instanceof BaseMessageAction) {
			BaseMessageAction action = (BaseMessageAction) obj;
			action.setPlayerID((GUID)Contexts.lookupInContexts("playerID"));
			action.setModuleID((String)Contexts.lookupInContexts("moduleID"));
			action.setSessionID((GUID)Contexts.lookupInContexts("sessionID"));
			action.setSrcService((String)Contexts.lookupInContexts("srcService"));
			action.setAccountID((GUID)Contexts.lookupInContexts("accountID"));
			
		}

		// 取得真正的类
		Class<?> clazz = IocContainer.getRealClass(obj.getClass());

		// 如果是代理类，则要取实际的类

		List<Field> fields = IocManager.getInFields(clazz);

		// 如果是null，则没有要带in的field
		if (fields == null || fields.size() == 0) {
			return;
		}

		for (Field field : fields) {
			try {
				In in = field.getAnnotation(In.class);
				String inName = in.name();
				// 如果没有名称，则按field的名称注入
				if (inName == null || inName.length() == 0) {
					inName = field.getName();
				}
				Object value = Contexts.lookupInContexts(inName);

				// 如果Contexts没有，并且要自动创建
				if (value == null && in.autoCreate()) {
					value = IocContainer.createObject(field.getType());
				}

				//if (value != null) {
					// log.info("Field In:" + inName + " " + value);
					field.set(obj, value);
				//}

			} catch (IllegalArgumentException e) {
				log.error("inObject" + obj, e);
			} catch (IllegalAccessException e) {
				log.error("inObject" + obj, e);
			}
		}
	}

	/**
	 * 对象注出
	 * 
	 * @param obj
	 */
	public static void outObject(Object obj) {
		// 如果对象==null，直接返回
		if (obj == null) {
			return;
		}

		// 取得真正的类
		Class<?> clazz = IocContainer.getRealClass(obj.getClass());

		List<Field> fields = IocManager.getOutFields(clazz);

		// 如果是null，则没有要带in的field
		if (fields == null) {
			return;
		}

		for (Field field : fields) {
			try {
				Out out = field.getAnnotation(Out.class);

				// name
				String outName = out.name();
				// 如果没有名称，则按field的名称注出
				if (outName == null || outName.length() == 0) {
					outName = field.getName();
				}

				// scopeType
				ScopeType scopetype = out.scopeType();
				// 如果没设置，则按event处理
				if (scopetype == null) {
					scopetype = ScopeType.EVENT;
				}

				// nullset
				boolean nullset = out.nullset();

				Object value = field.get(obj);

				// 如果value==null，也不需要往Context赋值
				if (value != null || nullset == true) {
					//log.info("Field Out:" + outName + " Value:" + value +" " + scopetype);
					Contexts.putInContexts(outName, value, scopetype);
				} else {
				}

			} catch (IllegalArgumentException e) {
				log.error("inObject" + obj, e);
			} catch (IllegalAccessException e) {
				log.error("inObject" + obj, e);
			}
		}
	}

}
